package com.qiall.boot.fileservice.impl;

import com.qiall.ali.Oss;
import com.qiall.assertutil.Assert;
import com.qiall.boot.fileability.FileService;
import com.qiall.boot.fileability.request.*;
import com.qiall.boot.fileservice.data.eitity.DirectInfo;
import com.qiall.boot.fileservice.data.eitity.FileInfo;
import com.qiall.boot.fileservice.data.eitity.enums.FileSourceTypeEnum;
import com.qiall.boot.fileservice.data.mapper.DirectMapper;
import com.qiall.boot.fileservice.data.mapper.FileInfoMapper;
import com.qiall.boot.fileservice.data.properties.OssProperties;
import com.qiall.boot.fileservice.trans.FileDataTrans;
import com.qiall.common.exception.BusinessResult;
import com.qiall.common.request.GetByIdRequest;
import com.qiall.user.ability.entity.UserInfoDTO;
import com.qiall.user.ability.service.user.UserService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 文件上传
 * 获取文件下载连接
 * 文件删除
 * 文件夹创建
 * 文件夹修改
 * 文件夹删除
 * 通过文件夹id获取文件列表
 * 通过文件夹id获取文件树
 */
@Component
@DubboService
public class FileServiceImpl implements FileService {

    @Autowired
    private FileInfoMapper fileInfoMapper;

    @Autowired
    private DirectMapper directMapper;

    @DubboReference
    private UserService userService;

    @Autowired
    OssProperties ossProperties;

    @Autowired
    private FileDataTrans fileDataTrans;

    @Autowired
    BaseFileServiceProxy baseFileServiceProxy;


    @Override
    public BusinessResult<Void> setFileUserInfo(SetFileInfoDTO setFileInfoDTO) {
        FileInfo fileInfo = new FileInfo();
        fileInfo.setId(setFileInfoDTO.getId());
        UserInfoDTO userInfoDTO = userService.getUserInfoByAuthCode(setFileInfoDTO).getBody();
        fileInfo.setUploaderId(userInfoDTO.getUserId());
        fileInfo.setDirectId(setFileInfoDTO.getDirectId());
        fileInfo.setId(setFileInfoDTO.getId());
        fileInfoMapper.update(fileInfo);
        return BusinessResult.success(null);
    }

    @Override
    public BusinessResult<String> getFileUrl(GetByIdRequest getByIdRequest) {
        FileInfo fileInfo = fileInfoMapper.select(getByIdRequest.getId());
        String fromId = fileInfo.getFromId();
        FileSourceTypeEnum fileSourceTypeEnum = FileSourceTypeEnum.ofCode(fileInfo.getFromType());
        String tmpUrl= baseFileServiceProxy.getBaseFileService(fileSourceTypeEnum).getDownLoadUrl(fromId);
        return BusinessResult.success(tmpUrl);
    }

    /**
     * 创建文件夹
     */
    @Override
    public BusinessResult<Void> createDir(CreateDirDTO createDirDTO) {
        DirectInfo directInfo = new DirectInfo();
        // 简单校验名称不能重复
        Integer parentId = createDirDTO.getParentId() == null ? DirectInfo.ROOT_ID : createDirDTO.getParentId();
        UserInfoDTO userInfoDTO = userService.getUserInfoByAuthCode(createDirDTO).getBody();
        List<DirectInfo> queryByParentId = directMapper.getByParentIdAndUserId(createDirDTO.getParentId(), userInfoDTO.getUserId());
        if (CollectionUtils.isNotEmpty(queryByParentId)) {
            List<DirectInfo> filterByName = queryByParentId.stream().filter(x -> x.getDirectName().equals(createDirDTO.getDirName())).collect(Collectors.toList());
            Assert.isNull(filterByName, "文件夹重名");
        }
        Integer maxId = directMapper.selectMaxId();
        Integer directId = maxId == null ? 1 : maxId + 1;
        directInfo.setCreatorId(directId);
        directInfo.setDirectName(createDirDTO.getDirName());
        directInfo.setParentId(parentId);
        directInfo.setId(directId);
        directMapper.insert(directInfo);
        return BusinessResult.success(null);
    }

    /**
     * 删除文件夹
     */
    @Override
    public BusinessResult<Void> remoteDir(GetByIdRequest request) {
        // 简单权限校验
        DirectInfo directInfo = directMapper.select(request.getId());
        Assert.notNull(directInfo, "文件夹不存在");
        UserInfoDTO userInfoDTO = userService.getUserInfoByAuthCode(request).getBody();
        Assert.isTrue(directInfo.getCreatorId().equals(userInfoDTO.getUserId()), "不是文件夹所属人无法删除");
        // 文件夹下面有文件无法删除
        List<DirectInfo> directInfos = directMapper.getByParentIdAndUserId(directInfo.getId(), userInfoDTO.getUserId());
        Assert.isNull(directInfos, "有子文件夹无法删除");
        List<FileInfo> fileInfos = fileInfoMapper.getByDirectId(directInfo.getId());
        Assert.isNull(fileInfos, "有子文件无法删除");
        //删除文件
        directMapper.delete(request.getId());
        return BusinessResult.success(null);
    }

    @Override
    public BusinessResult<List<DirDTO>> getDirList(GetDirRequest request) {
        UserInfoDTO userInfoDTO = userService.getUserInfoByAuthCode(request).getBody();

        List<DirectInfo> queryByParentId = directMapper.getByParentIdAndUserId(request.getParentId(), userInfoDTO.getUserId());
        if (CollectionUtils.isEmpty(queryByParentId)) {
            return BusinessResult.success(Lists.newArrayList());
        }
        List<DirDTO> dirDTOS = queryByParentId.stream().map(x -> {
            DirDTO dirDTO = new DirDTO();
            dirDTO.setId(x.getId());
            dirDTO.setParentId(x.getParentId());
            dirDTO.setDirName(x.getDirectName());
            return dirDTO;
        }).collect(Collectors.toList());
        return BusinessResult.success(dirDTOS);
    }

    @Override
    public BusinessResult<List<FileInfoDTO>> searchFile(GetFileRequest request) {
        UserInfoDTO userInfoDTO = userService.getUserInfoByAuthCode(request).getBody();
        Assert.notNull(userInfoDTO, "用户未登陆");
        // 查询文件信息
        List<FileInfo> fileInfos = fileInfoMapper.selectByUserIdFileNameAndDirId(userInfoDTO.getUserId(), request.getFileName(), request.getDirId());
        if (CollectionUtils.isEmpty(fileInfos)) {
            return BusinessResult.success(Lists.newArrayList());
        }
        List<FileInfoDTO> fileInfoDTOS = fileInfos.stream().map(x -> fileDataTrans.trans(x)).collect(Collectors.toList());
        return BusinessResult.success(fileInfoDTOS);
    }


    @Override
    public BusinessResult<Void> deleteFile(GetByIdRequest request) {
        UserInfoDTO userInfoDTO = userService.getUserInfoByAuthCode(request).getBody();
        Assert.notNull(userInfoDTO, "用户未登陆");
        // 查询文件信息
        FileInfo fileInfo = fileInfoMapper.select(request.getId());
        Assert.notNull(fileInfo, "文件不存在");
        Assert.isTrue(fileInfo.getUploaderId().equals(userInfoDTO.getUserId()), "不是所属文件上传者无法删除");
        // 先删除上的文件
        String fromId = fileInfo.getFromId();
        FileSourceTypeEnum fileSourceTypeEnum=  FileSourceTypeEnum.ofCode(fileInfo.getFromType());
        baseFileServiceProxy.getBaseFileService(fileSourceTypeEnum).deleteFie(fromId);
        // 删除文件信息
        fileInfoMapper.delete(request.getId());
        return BusinessResult.success(null);
    }

}
